// // https://shop64022682.taobao.com/ DIY模块地址
// #include <Arduino.h>
// #include "driver/timer.h" // 使用定时器所需头文件
// // SG90 PWM脉冲周期为20ms左右
// // ______
// // |    |___________________________________________| PWM波形示意图
// // 高电平为0.5ms-2.5ms
// // 高电平0.5ms和2.5ms分别对应舵机的0°和满行程度数
// // 下面是180°舵机的高电平时间与电机角度的对应关系
// // 0.5ms       0°
// // 1.0ms       45°
// // 1.5ms       90°
// // 2.0ms       135°
// // 2.5ms       180°
// // 本工程以10微秒为最小时间分度
// // (2.5毫秒-0.5毫秒)÷10微秒=200 
// // 180°÷200 = 0.9度 即本工程中电机的最小旋转角度为0.9度

// const int pwmPin = 4; // PWM脉冲输出引脚 DPIO15
// static unsigned int cntTimer = 0; // 定时器计数器，定时器中断每响一次，计数器加一，累积到20ms，置零重新累加
// unsigned int cntHigh = 50; // 设置高电平对应的定时器中断数，
// // 定时器初始化函数声明，设置定时器参数，并启动定时器
// void Time_Init(unsigned int usCnt);

// // 设置函数，只在程序启动后运行一次
// void setup() {
//   pinMode(pwmPin,OUTPUT); // 将PWM引脚设置为输出模式
//   Time_Init(10); // 设置定时器中断10微秒响一次
//   Serial.begin(9600); // 初始化并启动串口
// }
// // 循环函数，循环执行主程序
// void loop() {
//   cntHigh+=1; // 每个循环自加1，1对应10微秒高电平，对应SG90的旋转角度为0.9°
//   Serial.printf("===%d---%.2f°\r\n", cntHigh, 0.9*(cntHigh-50));// 从串口输出高电平计数器的值，及对应的SG90的输出轴角度
//   // 当高电平时间超过2.5ms（对应180°）时，则将高电平时间设为0.5ms（对应0°）
//   if(cntHigh > 250){
//     cntHigh = 50;
//     delay(1000);// 延时1秒，使电机有足够时间从180°位置回到0°位置
//   }
//   delay(25); // 延时25毫秒，让电机有足够时间旋转0.9°
// }
// //定时器中断回调函数,定时器中断响时，执行此函数中代码
// void IRAM_ATTR timer_group0_isr(void *para){
//    int timer_idx = (int) para;
//     uint32_t intr_status = TIMERG0.int_st_timers.val; //获取定时器中断状态 
//     if ((intr_status & BIT(timer_idx)) && timer_idx == TIMER_0) {
//       TIMERG0.int_clr_timers.t0_int_clr = 1; // 清除中断标志
//     } 
//     // TIMERG0.hw_timer[timer_idx].config.alarm_en = TIMER_ALARM_EN;  //再次使能alarm    
//     cntTimer++;// 中断每响一次，为10微秒，计数器加一
//     if(cntTimer<cntHigh)// cntHigh值在主循环(loop()函数)中设定
//     { 
//       // 若在高电平时间段内，PWM引脚输出高电平
//       digitalWrite(pwmPin, 1);
//     }else{
//       // 若在低电平时间段内，PWM引脚输出低电平
//       digitalWrite(pwmPin, 0);
//       if(cntTimer>=2000){
//         // 若超出20ms,则重新开始计数，开始一个新的脉冲周期
//         cntTimer=0;
//       }
//     }
// }
// // 定时器初始化函数，设置定时器参数，并启动定时器
// void Time_Init(unsigned int usCnt) {  
// 	timer_config_t config;// 设置定时器初始化参数
//   config.divider = 8; //分频系数
// 	config.counter_dir = TIMER_COUNT_UP; //计数方式为向上计数
// 	config.counter_en = TIMER_PAUSE; //调用timer_init函数以后不启动计数,调用timer_start时才开始计数
// 	config.alarm_en = TIMER_ALARM_EN; //到达计数值启动报警（计数值溢出，进入中断）
//   // config.auto_reload = 1; //自动重新装载预装值
//     config.auto_reload = TIMER_AUTORELOAD_EN; //自动重新装载预装值
//   // 初始化定时器
// 	timer_init(TIMER_GROUP_0,TIMER_0,&config); 
// 	// 设置定时器预装值
// 	timer_set_counter_value(TIMER_GROUP_0,TIMER_0,0x00000000ULL); 
// 	// 设置报警阈值 usCnt[定时usCnt 微秒] (TIMER_BASE_CLK[定时器时钟/8[分频系数]/1000/1000[延时为us级别，因此/1000/1000])
// 	timer_set_alarm_value(TIMER_GROUP_0,TIMER_0,usCnt*(TIMER_BASE_CLK/8/1000/1000)); //TIMER_BASE_CLK 为80M
// 	// 定时器中断使能
// 	timer_enable_intr(TIMER_GROUP_0,TIMER_0);
// 	// 注册定时器中断函数
// 	timer_isr_register(TIMER_GROUP_0,TIMER_0,
// 			timer_group0_isr,  //定时器中断回调函数
// 			(void*)TIMER_0,    //传递给定时器回调函数的参数
// 			ESP_INTR_FLAG_IRAM, //把中断放到 IRAM 中
// 			NULL //调用成功以后返回中断函数的地址,一般用不到
// 			);
// 	// 启动定时器
// 	timer_start(TIMER_GROUP_0,TIMER_0); //开始计数
// }


#include <Arduino.h>
#include <ESP32Servo.h>

const int pwmPin = 4; // 舵机信号线连接的引脚
Servo myservo;

void setup() {
  Serial.begin(9600);
  myservo.attach(pwmPin); // 连接舵机
}

void loop() {
  static int angle = 0;
  angle += 1; // 每次增加1度
  if (angle > 180) {
    angle = 0;
    delay(1000); // 到180°后停1秒
  }
  myservo.write(angle); // 设置舵机角度
  Serial.printf("Angle: %d°\r\n", angle);
  delay(25); // 每0.9°约25ms，和原逻辑类似
}